package model

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"gorm.io/gorm/clause"
	"server/common"
	"server/pkg/app"
	"server/service/ws"
)

type Status struct {
	Value string
}

type MinNode struct {
	Model
	IP       string `gorm:"column:ip;type:varchar(16);unique" json:"ip"`
	User     string `gorm:"column:user;type:varchar(16);NOT NULL" json:"user"`
	IbmcIP   string `gorm:"column:ibmc_ip;type:varchar(16)"`
	IbmcUser string `gorm:"column:ibmc_user;type:varchar(10)"`
	Describe string `gorm:"column:describe;type:varchar(200)"`
	Status   string `gorm:"column:status;type:varchar(200)"`

	Envs []Env `gorm:"many2many:env_node;ForeignKey:ID;References:ID" json:"envs"`

	OwnerID int `json:"owner_id"`
	Owner   Owner
}

// 节点详情表
type Node struct {
	MinNode

	PassWord   string `gorm:"column:password;type:varchar(32);NOT NULL;" json:"password"`
	IbmcPassWd string `gorm:"column:ibmc_password;type:varchar(32)" json:"ibmc_password"`

	Param string `gorm:"column:param;type:longtext" json:"param"`
}

func (node *Node) TableName() string {
	return "node"
}

func (node *MinNode) TableName() string {
	return "node"
}

func (node *Node) List(page *app.Page) ([]MinNode, int64) {
	nodes := []MinNode{}
	var count int64
	db := common.DB.Debug().Model(Node{}).Preload("Owner").Preload("Envs").Order("id desc")
	//db = db.Limit(page.Size).Offset((page.Page - 1) * page.Size)
	if err := db.Limit(page.Size).Offset((page.Page - 1) * page.Size).Find(&nodes).Offset(-1).Limit(-1).Count(&count).Error; err != nil {
		return nodes, count
	}
	return nodes, count
}

func (node *Node) Create() error {
	fmt.Println(node)
	if err := common.DB.Omit(clause.Associations).Create(&node).Error; err != nil {
		return err
	}
	return nil
}

func (node *Node) Info() *Node {
	if err := common.DB.Where("ip = ?", node.IP).Find(&node).Error; err != nil {
		return node
	}
	return node
}

func (node *Node) Update() error {
	if err := common.DB.Where("ip = ?", node.IP).Updates(&node).Error; err != nil {
		return err
	}
	return nil
}

func (node *Node) Delete() {

}

func (node *Node) CpuModel() string {
	node_info := node.Info()
	var cpu_model string
	client := app.SShClient{
		Host:     node_info.IP,
		Port:     22,
		User:     node_info.User,
		Password: node_info.PassWord,
	}
	cpu_model = client.Run("ls")
	fmt.Println(cpu_model)
	return cpu_model
}

func (node *Node) KernalInfo() string {
	node_info := node.Info()
	var cpu_model string
	client := app.SShClient{
		Host:     node_info.IP,
		Port:     22,
		User:     node_info.User,
		Password: node_info.PassWord,
	}
	hardware_name := client.Run("uname -m")
	kernel_name := client.Run("uname -s")
	kernel_plat := client.Run("uname -i")
	param := make(map[string]string)
	param["内核版本"] = hardware_name
	param["内核名称"] = kernel_name
	param["内核平台"] = kernel_plat
	param_string, err := json.Marshal(param)
	if err != nil {
		return ""
	}
	node.Param = string(param_string)
	node.Update()
	return cpu_model
}

func WsSsh(c *gin.Context) {
	fmt.Println("node WsSsh")
	ws.NodeWsSsh(c.Writer, c.Request)
}
